package view;

import boardGenerator.Pair;
import controllers.SudokuController;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import org.netbeans.lib.awtextra.AbsoluteConstraints;
import org.netbeans.lib.awtextra.AbsoluteLayout;

/**
 * Clase vista Principal
 */
public class MainView extends IMainView {    
    private JFrame jfWindow;
    private Celda[][] matriz;
    private JLabel time;
    private JLabel puntos;
    private JLabel numRestantes;
    private Color color1 = Color.GRAY;
    private Color color2 = Color.LIGHT_GRAY;    
    private Color fontColor = Color.WHITE;
    private Color wrongCell = Color.RED;
    private Color fontColorNoEditable = Color.DARK_GRAY;    
    private Color correctColor = Color.GREEN;
    private Color selectedColor = Color.YELLOW;
    private Color caretColor = selectedColor;
    private Color fontColorPista = Color.magenta;
    private JButton butStart; 
    private JButton butSolve;
    private JButton butHint;
    private JButton butCheck;
    private JButton butReset;
    private JButton butTopTen;
    private JButton butStop;
    private JButton butRules;
    private JButton butWeb;
    private JRadioButton radHard;
    private JRadioButton radModerate;
    private JRadioButton radEasy;
    private JTextField player;
    private JButton butView;
    /*Listener Para el movimiento y las teclas*/
    private KeyListener keyList1 = new KeyAdapter() {public void keyTyped(KeyEvent evt) {Teclea(evt);}};
    private KeyListener keyList2 = new KeyAdapter() {public void keyPressed(KeyEvent evt) {Mover(evt);}};
    private FocusListener focusList1 = new FocusAdapter() {public void focusGained(FocusEvent evt) {textFieldFocusGained(evt);}};
    private FocusListener focusList2 = new FocusAdapter() {public void focusLost(FocusEvent evt) {textFieldFocusLost(evt);}};
    private MouseListener mouseList1 = new MouseAdapter() {public void mouseClicked(MouseEvent evt) {formMouseClicked(evt);}};
        

    /**
     * Constructor de la vista principal
     * inicializa los componentes
     */
    public MainView(){
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e){
            e.printStackTrace();
        }
        jfWindow = new JFrame();
        jfWindow.setMinimumSize(new Dimension(420,420));        
        //Segun la dimension de la pantalla (resolucion) tamaño y posicion de la ventana default
        Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize();
        Point framePos=new Point((int)(screenSize.width)/2-350,(int)(screenSize.height)/2-300);
        jfWindow.setLocation(framePos);
        //Dimension frameSize = new Dimension((int)(screenSize.width),(int)(screenSize.height));
        //jfWindow.setBounds(0,0,frameSize.width,frameSize.height);
        jfWindow.setIconImage(Toolkit.getDefaultToolkit().getImage(IMainView.class.getResource("/resources/sudoku-icon.png")));
        //Renombro el cartel
        jfWindow.setTitle("BigSudoku");        
        //Configuro los Contenedores de la Ventana
        Container container = jfWindow.getContentPane();
        setupMainContainer(container);
        //Configuro las caracteristicas de la Ventana
        jfWindow.pack();
        jfWindow.setVisible(true);
        jfWindow.setResizable(false);
        jfWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        for (Component comp :jfWindow.getComponents()){
            comp.addMouseListener(new MouseAdapter() {public void mouseClicked(MouseEvent evt) {formMouseClicked(evt);}});
        }        
    }
    
    /**
     * Inicializa el contenedor principal del JFrame
     * @param container 
     */
    private void setupMainContainer(Container container){
        /*Panel izquierdo*/
        JPanel tmp = new JPanel();        
        tmp.setLayout(new AbsoluteLayout());
        tmp.add(informacion(),new AbsoluteConstraints(10, 10, -1, -1));
        tmp.add(jugador(),new AbsoluteConstraints(10, 95, -1, -1));
        tmp.add(dificultad(),new AbsoluteConstraints(10, 150, -1, -1));
        tmp.add(botones(),new AbsoluteConstraints(50, 245, -1, -1));
        
        container.setLayout(new BorderLayout());
        container.add(tmp,BorderLayout.LINE_END);        
        container.add(tablero(),BorderLayout.CENTER);
    }
    
    /**
     * Crea el panel de informacion del juego actual
     * @return 
     */
    private JPanel informacion(){
        JPanel info = new JPanel();
        JPanel datos = new JPanel();
        datos.setLayout(new GridLayout(3,2,2,2));
        datos.setPreferredSize(new Dimension(160, 80));
        datos.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Partida", TitledBorder.CENTER, TitledBorder.TOP, null, null));
        
        JLabel timeText = new JLabel("Tiempo: ");
        time = new JLabel();
        time.setText("00:00:00");
        timeText.setHorizontalAlignment(JLabel.RIGHT);
        datos.add(timeText);
        datos.add(time);
        
        JLabel numText = new JLabel("Faltan: ");
        numRestantes = new JLabel();
        numRestantes.setText("81");
        numText.setHorizontalAlignment(JLabel.RIGHT);
        datos.add(numText);
        datos.add(numRestantes);
        
        JLabel puntText = new JLabel("Puntuacion: ");
        puntos = new JLabel();
        puntos.setText("0");
        puntText.setHorizontalAlignment(JLabel.RIGHT);
        datos.add(puntText);
        datos.add(puntos);
        
        info.add(datos);
        return info;
    }
    
    /**
     * Crea el panel de botones del juego
     * @return 
     */
    private JPanel botones(){
        
        JPanel info = new JPanel();
        info.setLayout(new GridLayout(10,0,3,3)); 
        info.setSize(50, 50);
        
        /**
         * Boton iniciar Juego
         */
        butStart = new JButton();                
        butStart.addActionListener(SudokuController.getInstance());
        butStart.setActionCommand("START_GAME");
        butStart.setText("Nuevo");
        butStart.setSize(20, 20);
        butStart.setEnabled(true);
        info.add(butStart);
        
        /**
         * Boton Resolver Juego
         */
        butSolve = new JButton();        
        butSolve.addActionListener(SudokuController.getInstance());
        butSolve.setActionCommand("SOLVE_GAME");
        butSolve.setText("Resolver");
        butSolve.setEnabled(false);
        info.add(butSolve);
        
        /**
         * Boton Verificar juego
         */
        butCheck = new JButton();
        butCheck.addActionListener(SudokuController.getInstance());
        butCheck.setActionCommand("CHECK_GAME");
        butCheck.setText("Verificar");
        butCheck.setEnabled(false);
        info.add(butCheck);
        
        /**
         * Boton Obtener Pista
         */
        butHint = new JButton();       
        butHint.addActionListener(SudokuController.getInstance());
        butHint.setActionCommand("GET_HINT");
        butHint.setText("Pista");
        butHint.setEnabled(false);
        info.add(butHint);
        
        /**
         * Boton Resetear Partida
         */
        butReset = new JButton();       
        butReset.addActionListener(SudokuController.getInstance());
        butReset.setActionCommand("RESET_GAME");
        butReset.setText("Reiniciar");
        butReset.setEnabled(false);
        info.add(butReset);
        
        /**
         * Boton detener Partida
         */
        butStop = new JButton();       
        butStop.addActionListener(SudokuController.getInstance());
        butStop.setActionCommand("STOP_GAME");
        butStop.setText("Finalizar");
        butStop.setEnabled(false);
        info.add(butStop);
                
        /**
         * Boton top10
         */
        butTopTen = new JButton();       
        butTopTen.addActionListener(SudokuController.getInstance());
        butTopTen.setActionCommand("TOP_TEN");
        butTopTen.setText("Top Ten");
        butTopTen.setEnabled(true);
        info.add(butTopTen);
        
        /**
         * Boton sudokuonline
         */
        butWeb = new JButton();       
        butWeb.addActionListener(SudokuController.getInstance());
        butWeb.setActionCommand("SUDOKU_WEB");
        butWeb.setText("Sudoku Online");
        butWeb.setEnabled(true);
        info.add(butWeb);
        
        /**
         * Boton Reglas Sudoku
         */
        butRules = new JButton();
        butRules.addActionListener(SudokuController.getInstance());
        butRules.setActionCommand("RULES");
        butRules.setText("Reglas Sudoku");
        butRules.setEnabled(true);
        info.add(butRules);
        
        /**
         * Boton cambiar interfaz
         */
        butView = new JButton();       
        butView.addActionListener(SudokuController.getInstance());
        butView.setActionCommand("OTHER_VIEW");
        butView.setText("Cambiar Vista");
        butView.setEnabled(true);
        info.add(butView);
        
        return info;
    }
    
    /**
     * Crea el panel selector de dificultad
     * @return 
     */
    private JPanel dificultad(){
        JPanel info = new JPanel();
        /**
         * Botones Radio Mutuamente Excluyentes
         */
        radHard = new JRadioButton();        
        radModerate = new JRadioButton();        
        radEasy = new JRadioButton();        
        radHard.setText("Dificil");
        radModerate.setText("Moderado");
        radEasy.setText("Facil");
        radHard.setActionCommand("DIF_HARD");
        radModerate.setActionCommand("DIF_MODERATE");
        radEasy.setActionCommand("DIF_EASY");
        radHard.addActionListener(SudokuController.getInstance());
        radModerate.addActionListener(SudokuController.getInstance());
        radEasy.addActionListener(SudokuController.getInstance());        
        radHard.setEnabled(true);
        radModerate.setEnabled(true);
        radEasy.setEnabled(true);
        
        ButtonGroup group = new ButtonGroup();
        group.add(radHard);
        group.add(radModerate);
        group.add(radEasy);
        JPanel panel = new JPanel();        
        panel.setPreferredSize(new Dimension(160, 80));
        panel.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Dificultad", TitledBorder.CENTER, TitledBorder.TOP, null, null));
        panel.setLayout(new GridLayout(0, 1, 0, 0));
        panel.add(radEasy);        
        panel.add(radModerate);
        panel.add(radHard);
        String diff = SudokuController.getInstance().getConfiguration().getDifficulty().toString();                
        switch (diff){
            case "EASY": radEasy.setSelected(true); break;
            case "HARD":radHard.setSelected(true);break;
            case "MODERATE":radModerate.setSelected(true);break;
        }
        info.add(panel);
        
        return info;
    }
    
    /**
     * Panel Nombre de Jugador
     * @return 
     */
    private JPanel jugador(){        
        JPanel info = new JPanel();
        JPanel panel = new JPanel();        
        panel.setPreferredSize(new Dimension(160, 50));
        panel.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Jugador", TitledBorder.CENTER, TitledBorder.TOP, null, null));
        player = new JTextField(17);
        player.setText(SudokuController.getInstance().getConfiguration().getNamePlayer());        
        panel.add(player);
        info.add(panel);
        
        return info;
    }
    
    /**
     * Panel tablero Sudoku
     * @return 
     */
    private JPanel tablero(){
        JPanel superior = new JPanel();
        superior.setLayout(new AbsoluteLayout());
        JPanel tablero = new JPanel();
        Dimension dim = new Dimension(500,500);
        tablero.setMaximumSize(dim);
        tablero.setPreferredSize(dim);
        tablero.setSize(dim);        
        tablero.setLayout(new GridLayout(9,9,2,2));
        crearMatriz();
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                tablero.add(matriz[i][j]);
            }            
        }
        superior.add(tablero,new AbsoluteConstraints(10, 10, -1, -1));        
        return superior;
    }
    
    /**
     * Crea la matriz de Celdas JTextField del juego
     */
    private void crearMatriz(){
        matriz = new Celda[9][9];
        Celda tmp;
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                tmp = new Celda();
                tmp.setColumns(1);
                tmp.setFont(new java.awt.Font("Tahoma", 0, 18));
                tmp.setForeground(fontColor);                
                tmp.setHorizontalAlignment(javax.swing.JTextField.CENTER);
                tmp.setBorder(javax.swing.BorderFactory.createEtchedBorder());
                tmp.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
                tmp.setMargin(new java.awt.Insets(0, 0, 0, 0));
                tmp.setMaximumSize(new java.awt.Dimension(4, 4));
                tmp.setMinimumSize(new java.awt.Dimension(4, 4));
                tmp.setPreferredSize(new java.awt.Dimension(4, 4));
                tmp.setSize(4,4);
                tmp.setInputVerifier(new IntegerInput());                
                tmp.setEditable(false);
                tmp.setEnabled(false);                
                tmp.setCursor(new Cursor(Cursor.HAND_CURSOR));
                tmp.setCaretColor(caretColor);
                tmp.setKeymap(null);
                tmp.setFil(i);
                tmp.setCol(j);
                if (((i<3 || i>5)&&(j<3||j>5)) || (i>2 && i<6 && j>2 && j<6)){
                    tmp.setNormalColor(color2);
                } else {
                    tmp.setNormalColor(color1);
                }
                tmp.setWrong(false);
                matriz[i][j] = tmp;
            }
        }
    }
    
    /**
     * Habilita los controles del juego (botones de interaccion)
     * @param var 
     */
    public void habilitarControles(boolean var){        
        this.butStart.setEnabled(!var);
        this.radHard.setEnabled(!var);
        this.radModerate.setEnabled(!var);
        this.radEasy.setEnabled(!var);        
        this.butCheck.setEnabled(var);
        this.butHint.setEnabled(var);
        this.butSolve.setEnabled(var);
        this.butReset.setEnabled(var);
        this.butStop.setEnabled(var);
        this.butView.setEnabled(!var);
        this.butTopTen.setEnabled(!var);        
        this.butWeb.setEnabled(!var);
        this.butRules.setEnabled(!var);
    }

    /**
     * Habilita la interaccion con el tablero
     */
    public void habilitarTablero(){        
        this.normalizeBoard();
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                Celda tmp = matriz[i][j];
                tmp.setEditable(true);
                tmp.setEnabled(true);
                tmp.addKeyListener(this.keyList1);
                tmp.addKeyListener(this.keyList2);
                tmp.addFocusListener(this.focusList1);
                tmp.addFocusListener(this.focusList2);
                tmp.addMouseListener(this.mouseList1);
            }
        }
    }
    
    /**
     * Deshablita la interaccion con el tablero
     */
    public void deshabilitarTablero(){
        for (int i = 0; i < 9; i++) {
                for (int j = 0; j < 9; j++){
                    Celda tmp = matriz[i][j];
                    tmp.setEditable(false);
                    tmp.setEnabled(false);
                    tmp.removeKeyListener(this.keyList1);
                    tmp.removeKeyListener(this.keyList2);
                    tmp.removeFocusListener(this.focusList1);
                    tmp.removeFocusListener(this.focusList2);
                    tmp.removeMouseListener(this.mouseList1);
                }
            }
    }
    
    /**
     * Actualiza el contador de tiempo
     * @param time 
     */
    public void refreshTime(String time){
        this.time.setText(time);
    }
    
    /**
     * Actualiza el contador de puntuacion
     * @param punt 
     */
    public void refreshPuntuacion(String punt){
        this.puntos.setText(punt);
    }
    
    /**
     * Actualiza el contador de numeros restantes
     * @param num 
     */
    public void refreshContador(String num){
        this.numRestantes.setText(num);
    }
    
    /**
     * Establece la matriz del tablero
     * @param param matriz de enteros de 9x9
     */
    public void setMatriz(int[][] param){
        this.normalizeBoard();
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                setNum(i,j,param[i][j]);
            }            
        }        
    }    
    
    /**
     * Obtiene toda la Matriz del Tablero
     * @return  matriz de enteros de 9x9
     */
    public int[][] getMatriz(){
        int[][] result = new int[9][9];
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                result[i][j] = getNum(i,j);
            }            
        }        
        return result;
    }
    
    /**
     * Establece un valor para una celda del tablero dado
     * @pre   -1<fil<9 and -1<col<9
     * @param fil pos de fila
     * @param col pos de columna
     * @param value valor
     */
    public void setNum(int fil,int col,int value){
        if (value == 0){            
            matriz[fil][col].setText("");
            matriz[fil][col].setEnabled(true);
            matriz[fil][col].setEditable(true);
            matriz[fil][col].setFont(new java.awt.Font("Tahoma", 1, 20));
        } else {            
            matriz[fil][col].setText(String.valueOf(value));
            matriz[fil][col].setEnabled(false);
            matriz[fil][col].setEditable(false);
            matriz[fil][col].setFont(new java.awt.Font("Tahoma", 2, 18));
            matriz[fil][col].setDisabledTextColor(fontColorNoEditable);
        }
    }    
    
    /**
     * Pone un valor en el tablero como si fuese
     * una pista, en otro color y no editable
     * @param fil posicicon fila
     * @param col posicion columna
     * @param value numero a ingresar
     */
    public void setPista(int fil,int col,int value){
        matriz[fil][col].setText(String.valueOf(value));
        matriz[fil][col].setEnabled(false);
        matriz[fil][col].setEditable(false);
        matriz[fil][col].setDisabledTextColor(fontColorPista);
    }
    
    /**
     * Establece una celda como incorrecta
     * @param fil
     * @param col 
     */    
    public void setWrong(int fil,int col){        
        matriz[fil][col].setBackground(wrongCell);
        matriz[fil][col].setWrong(true);
    }
    
    /**
     * Establece una celda como normal
     * @param fil
     * @param col 
     */    
    public void setNormal(int fil,int col){
        matriz[fil][col].setBackground(matriz[fil][col].getNormalColor());
        matriz[fil][col].setWrong(false);
    }
    
    /**
     * Establece una celda como correcta
     * @param fil
     * @param col 
     */    
    public void setCorrect(int fil,int col){
        matriz[fil][col].setForeground(correctColor);
    }
    
    
    /**
     * Obtiene el valor de una celda. Si este valor no es
     * numerico devuelve un -1
     * @pre   -1<fil<9 and -1<col<9
     * @param fil pos de fila
     * @param col pos de columna
     * @return 
     */
    public int getNum(int fil,int col){
        try {
            return Integer.valueOf(matriz[fil][col].getText());
        } catch (Exception e){
            return 0;
        }
    }
    
    /**
     * Obtiene el nombre del jugador actual     * 
     * @return string con el nombre
     */
    public String getPlayerName(){
        return this.player.getText();
    }
    
    /**
     * Establece el nombre del jugador actual
     * @param nombre
     */
    public void setPlayerName(String nomb){
        this.player.setText(nomb);
    }
    
    /**
     * Muestra un mensage de advertencia por pantalla
     */
    public void showWarningMessage(String msg){
        JOptionPane.showMessageDialog(null,msg," Advertencia",JOptionPane.WARNING_MESSAGE);
    }
    
    /**
     * Muesta un mensage de informacion por pantalla
     */
    public void showInfoMessage(String msg){
        JOptionPane.showMessageDialog(null,msg," Informacion",JOptionPane.INFORMATION_MESSAGE);
    }
    
    /**
     * Muestra un mensaje de confirmacion por pantalla
     * @return true/false segun desicion 
     */
    public boolean showConfirmationMessage(String msg){
        //int i = JOptionPane.showConfirmDialog(null, msg, " Confirmacion", JOptionPane.YES_NO_OPTION);        
        //return (i == JOptionPane.YES_OPTION);
        return true;
    }
    
    /**
     * Cierra la ventana actual
     */
    public void dispose(){
        this.jfWindow.dispose();
    }

    /**
     * Evita la interaccion con la ventana actual
     * @param val 
     */
    public void disable(Boolean val) {
        this.jfWindow.setEnabled(!val);
    }
    
    /**
     * Reclama el foco hacia la ventana principal
     * y la trae al frente
     */
    public void requestFocus(){
        this.jfWindow.requestFocus();        
        this.jfWindow.toFront();        
    }
    
    
    /**
     * Verifica que solo ponga numeros entre 0 y 9
     */
    private class IntegerInput extends InputVerifier{        
        @Override
        public boolean verify(JComponent input) {
            JTextField tmp = (JTextField)input;
            String text = tmp.getText();
            int num;
            if (text.length()==0){
                return true;
            } else {
                try {
                    num = Integer.parseInt(text);
                } catch (Exception e) {
                    tmp.setText("");
                    return false;
                }
                if (num<0 || num >9){
                    tmp.setText("");
                    return false;
                } else {
                    return true;
                }
            }            
        }        
    }    
    
    /**
     * Punta el Tablero (fondo) con los colores normales
     */    
    private void normalizeBoard(){
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                matriz[i][j].setBackground(matriz[i][j].getNormalColor());
            }
        }        
    }
    
    /**
     * Evita poner otra cosa que no sea un numero del 1..9
     * @param evt 
     */
    private void Teclea(KeyEvent evt){
        Celda tmp = (Celda) evt.getComponent();
        switch (evt.getKeyChar()) {
            case '1': tmp.setText("1");insert(tmp,1);break;
            case '2': tmp.setText("2");insert(tmp,2);break;
            case '3': tmp.setText("3");insert(tmp,3);break;
            case '4': tmp.setText("4");insert(tmp,4);break;
            case '5': tmp.setText("5");insert(tmp,5);break;
            case '6': tmp.setText("6");insert(tmp,6);break;
            case '7': tmp.setText("7");insert(tmp,7);break;
            case '8': tmp.setText("8");insert(tmp,8);break;
            case '9': tmp.setText("9");insert(tmp,9);break;            
        }
    }
    
    /**
     * Inserta un numero en la celda seleccionada infroma al observador
     * @param field
     * @param value 
     */
    private void insert(Celda field, int value){
        field.setWrong(false);
        Pair<Pair<Integer,Integer>,Integer> tmp = new Pair<Pair<Integer,Integer>,Integer>();
        Pair<Integer,Integer> pos = new Pair(field.getFil(),field.getCol());
        tmp.setFirst(pos);tmp.setSecond(value);        
        setChanged();
        notifyObservers(tmp);     
    }
    
    /**
     * Permite desplazarce en la grilla con las 
     * teclas de direccion y borrar elementos con supr y delete
     * @param evt 
     */
    private void Mover(KeyEvent evt){
        int dir = evt.getKeyCode();        
        Celda actual = (Celda) evt.getComponent();
        int fil = actual.getFil();
        int col = actual.getCol();     
        switch (dir){
            case 40: moverAbajo(fil,col);break;
            case 38: moverArriba(fil,col);break;
            case 37: moverIzquierda(fil,col);break;
            case 39: moverDerecha(fil,col);break;
            case 8: case 127: /*Borra valor*/
                        insert(actual,0);
                        actual.setText("");break;
        }        
    }
    
    /**
     * Mueve el foco una fila abajo
     * @param fil
     * @param col 
     */
    private void moverAbajo(int fil, int col){
        if (fil+1<9){
            while (!matriz[fil+1][col].isEnabled() && fil+1<9){
                fil++;
                if (fil+1>8) fil = -1;
            }
        }
        if (fil+1>8){
           moverAbajo(-1,col);
        } else {
            matriz[fil+1][col].requestFocus();
        }
    }
    
    /**
     * Mueve el foco una celda a la derecha
     * @param fil
     * @param col 
     */
    private void moverDerecha(int fil, int col){
        if (col+1<9){
            while (!matriz[fil][col+1].isEnabled() && col+1<9){
                col++;
                if (col+1>8) col = -1;
            }
        }
        if (col+1>8){
           moverDerecha(fil,-1);
        } else {
            matriz[fil][col+1].requestFocus();
        }
    }
    
    /**
     * Mueve el foco una fila arriba
     * @param fil
     * @param col 
     */
    private void moverArriba(int fil, int col){
        if (fil-1>-1){
            while (!matriz[fil-1][col].isEnabled() && fil-1>-1){
                fil--;
                if (fil-1<0) fil = 9;
            }
        }
        if (fil-1<0){
           moverArriba(9,col);
        } else {
            matriz[fil-1][col].requestFocus();
        }
    }
    
    /**
     * Mueve el foco una celda a la derecha
     * @param fil
     * @param col 
     */
    private void moverIzquierda(int fil, int col){
        if (col-1>-1){
            while (!matriz[fil][col-1].isEnabled() && col-1>-1){
                col--;
                if (col-1<0) col = 9;
            }
        }
        if (col-1<0){
           moverIzquierda(fil,9);
        } else {
            matriz[fil][col-1].requestFocus();
        }
    }
    
    /**
     * Cuando la celda gana el foco se pinta de otro color
     * @param evt 
     */
    private void textFieldFocusGained(FocusEvent evt){        
        ((Celda)evt.getSource()).setBackground(selectedColor);
    }
    
    /**
     * Cuando la celda pierde el foco recupera color original
     * @param evt 
     */
    private void textFieldFocusLost(FocusEvent evt){
        Celda tmp = (Celda)evt.getSource();
        if (tmp.isWrong()) 
            tmp.setBackground(wrongCell);
        else
            tmp.setBackground(tmp.getNormalColor());
    }
    
    /**
     * Cuando hago clic derecho quito el foco actual
     * @param evt 
     */
    private void formMouseClicked(java.awt.event.MouseEvent evt) {
        if ((evt.getModifiers() & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK){
                jfWindow.requestFocus();
        }
    }    
}


